#include <algorithm>
#include <cstdio>
#include <cstring>
#include <stack>

const int N = 100005, bit = 17;
int n, m, t, q, ccid, low[N], tmp[N], dep[N << 1], f[bit][N << 1], dis[N << 1];
std::stack<int> stk;

struct Graph {
  int e_cnt, cnt, heads[N << 1], dfn[N << 1];

  struct Edge {
    int v, nxt;
  };
  Edge e[N << 2];

  inline virtual void add(int u, int v) {
    e[++e_cnt].v = u, e[e_cnt].nxt = heads[v], heads[v] = e_cnt;
    e[++e_cnt].v = v, e[e_cnt].nxt = heads[u], heads[u] = e_cnt;
  }

  inline void clear() {
    e_cnt = 0, cnt = 0, ccid = n;
    memset(dfn, 0, sizeof(dfn));
    memset(low, 0, sizeof(low));
    memset(heads, 0, sizeof(heads));
  }
} E, G;

struct DGraph : Graph {
  inline void add(int u, int v) override {
    e[++e_cnt].v = v, e[e_cnt].nxt = heads[u], heads[u] = e_cnt;
    e[++e_cnt].v = u, e[e_cnt].nxt = heads[v], heads[v] = e_cnt;
    printf("%d %d\n", u, v);
  }
};

void tarjan(int u) {
  E.dfn[u] = low[u] = ++E.cnt;
  stk.push(u);
  for (int i = E.heads[u], v; i; i = E.e[i].nxt) {
    if (!E.dfn[v = E.e[i].v]) {
      tarjan(v);
      low[u] = std::min(low[u], low[v]);
      if (low[v] == E.dfn[u]) {
        ++ccid;
        for (int tmp = 0; tmp != v;) {
          tmp = stk.top(), stk.pop();
          G.add(ccid, tmp);
        }
        G.add(ccid, u);
      }
    } else
      low[u] = std::min(low[u], E.dfn[v]);
  }
}

void dfs(int u) {
  G.dfn[u] = ++G.cnt;
  for (int i = G.heads[u], v; i; i = G.e[i].nxt) {
    if ((v = G.e[i].v) != f[0][u]) {
      dep[v] = dep[u] + 1, f[0][v] = u;
      dis[v] = dis[u] + (v <= n ? 1 : 0);
      dfs(v);
    }
  }
}

inline int lca(int x, int y) {
  if (dep[x] < dep[y]) std::swap(x, y);
  for (int i = bit - 1; ~i; --i) {
    if (dep[f[i][x]] >= dep[y]) x = f[i][x];
  }
  if (x == y) return x;
  for (int i = bit - 1; ~i; --i) {
    if (f[i][x] != f[i][y]) x = f[i][x], y = f[i][y];
  }
  return f[0][x];
}

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("testdata.in", "r", stdin);
  freopen("testdata.out", "w", stdout);
#else
  freopen("P4606 [SDOI2018]战略游戏.in", "r", stdin);
  freopen("P4606 [SDOI2018]战略游戏.out", "w", stdout);
#endif
#endif

  scanf("%d", &t);
  while (t--) {
    scanf("%d%d", &n, &m);
    E.clear(), G.clear();
    for (int i = 1, u, v; i <= m; ++i) {
      scanf("%d%d", &u, &v);
      E.add(u, v);
    }
    tarjan(1);
    stk.pop();
    f[0][1] = 1;
    dfs(1);
    for (int i = 1; i < bit; ++i) {
      for (int j = 1; j <= ccid; ++j) f[i][j] = f[i - 1][f[i - 1][j]];
    }
    scanf("%d", &q);
    int s;
    while (q--) {
      scanf("%d", &s);
      for (int i = 1; i <= s; ++i) scanf("%d", &tmp[i]);
      std::sort(tmp + 1, tmp + s + 1,
                [](const int &lhs, const int &rhs) { return G.dfn[lhs] < G.dfn[rhs]; });
      int ans = -(s << 1);
      for (int i = 1; i < s; ++i) {
        ans += dis[tmp[i]] + dis[tmp[i + 1]] - (dis[lca(tmp[i], tmp[i + 1])] << 1);
      }
      ans += dis[tmp[1]] + dis[tmp[s]] - (dis[lca(tmp[1], tmp[s])] << 1);
      if (lca(tmp[1], tmp[s]) <= n) ans += 2;
      printf("%d\n", ans >> 1);
    }
  }
  return 0;
}